package cn.linjianhui.cluster.dao;

import lombok.var;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public abstract class BaseSqlProvider {

    private static final char UNDERLINE = '_';

    protected <T> String insertUpdateBatch(List<T> list, String tableName) {
        if (tableName == "" || tableName == null) {
            throw new NullPointerException("表名不能为空");
        }
        if (list == null || list.size() <= 0) {
            throw new NullPointerException("插入参数不能为空");
        }
        String sql;
        List<String> fieldNames = getFiledName(list.get(0));
        List<String> fieldNamesToSQL = fieldNames.stream().map(a -> camelToUnderline(a)).collect(Collectors.toList());
        sql = String.format("insert into %s (%s) values", tableName, String.join(",", fieldNamesToSQL));
        List<String> values = new ArrayList<>();
        for (var d : list) {
            List<String> str = new ArrayList<>();
            for (var field : fieldNames) {
                var fieldValue = getFieldValueByName(field, d);
                if (fieldValue == null) {
                    str.add("null");
                } else {
                    str.add("'" + fieldValue.toString() + "'");
                }
            }
            values.add("(" + String.join(",", str) + ")");
        }
        sql += String.join(",", values);
        sql += " ON DUPLICATE KEY UPDATE " + String.join(",", fieldNamesToSQL.stream().map(t -> t + " = VALUES(" + t + ")").collect(Collectors.toList()));
        return sql;
    }


    /**
     * 驼峰格式字符串转换为下划线格式字符串
     *
     * @param param
     * @return
     */
    private static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 获取属性名数组
     */
    private static List<String> getFiledName(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        List<String> fieldNames = new ArrayList<>();
        for (int i = 0; i < fields.length; i++) {
            fieldNames.add(fields[i].getName());
        }
        return fieldNames;
    }

    /**
     * 根据属性名获取属性值
     */
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(o, new Object[]{});
            return value;
        } catch (Exception e) {
            return null;
        }
    }
}
